import { Component, OnInit, ViewEncapsulation, AfterViewInit, Input } from '@angular/core';
import { Router, ActivatedRoute } from "@angular/router";
import { Store } from "@ngrx/store";
import { Observable } from "rxjs/Observable";
import { Observer } from "rxjs/Observer";
import { Subject } from "rxjs/Subject";
import { Subscription } from "rxjs/Subscription";
import { CmHttp } from "CmHttp";
import { SocketService } from "socket";
import { QuoteHeaders, TableOptions, QuoteHeader } from "./../../quote/quote-table/quote-table.component";
import { QuoteTableService } from "./../../quote/quote-table/quote-table.service";
import { LoadingService } from "./../../shared/loading.service";
import { ResizingService } from "utils";
import { BASEURL, STOCKURL } from "shared";
import * as _ from "lodash";
import "./../../shared/rxjs-operators";

const getParams = symbols => {
  return symbols.reduce((str, symbol) => `${str}symbol=${symbol}&`, "?");
};

const getValues = (obj: Object) => Object.keys(obj).map(key => obj[key]);

const defaultTableOptions = {
  subscribe: {
    enabled: false,
    channels: []
  },
  autoClickFirst: true,
  responsive: {
    enabled: true,
    rowHeight: 30
  },
  parts: {
    pagination: true,
    caption: false,
    sort: true,
    header: true
  }
};

export class BlockQuote {
  symbol: string;
  name: string;
  market: string;
  current?: number;
  change_rate?: number;
  change_amount?: number;
}

@Component({
  selector: 'stock-block',
  templateUrl: 'stock-block.component.html',
  encapsulation: ViewEncapsulation.None,
  styleUrls: [
    "stock-block.component.less"
  ],
  providers: [QuoteTableService, SocketService]
  // inputs: ["stockSource"]
})
export class StockBlockComponent implements OnInit, AfterViewInit {
  @Input() stockSource; // : string;
  params;
  blockParams;
  blockSub;
  stockParams;
  tabSub;
  _options;
  set options(customOptions) {
    this._options = _.merge({}, defaultTableOptions, customOptions);
    // this._options = Object.assign({}, defaultTableOptions, customOptions);
  }
  get options(): TableOptions {
    return this._options;
  }
  // block list
  blockList = [];
  // block show data
  blockData = [];
  // chosen block
  currentBlock: BlockQuote;  // 当前选中的板块

  blockTableOptions: TableOptions = {
    autoClickFirst: true,

    subscribe: {
      enabled: true,
      channels: ["watchlist"]
    },
    responsive: {
      enabled: true,
      rowHeight: 24
    },
    parts: {
      pagination: false,
      caption: false,
      sort: true,
      header: false
    }
  };

  stockTableOptions: TableOptions = {
    autoClickFirst: false,
    localSort: ["current", "symbol", "change_rate", "change", "amount_in", "volume"],
    subscribe: {
      enabled: true,
      channels: ["dynPanel"]
    },
    responsive: {
      enabled: true,
      rowHeight: 30
    },
    parts: {
      sort: true,
    }
  };

  blockHeaders: QuoteHeaders = {
    headHeader: undefined,
    bodyHeader: [
      {
        label: "版块名称",
        key: "name",
      },
      {
        label: "涨幅",
        key: "change_rate",
        withUpOrDown: true,
        withPercent: true,
        class: ["text-right"]
      }
    ]
  };
  subscription: Subscription;

  quoteHeaders: QuoteHeaders = require("./stock-block.headers.json");

  constructor(private http: CmHttp,
    private quoteTable: QuoteTableService,
    private activatedRoute: ActivatedRoute,
    private router: Router,
    private socket: SocketService,
    private loader: LoadingService,
    private resizing: ResizingService
    ) {
    this.blockSub = new Subject();
    this.tabSub = new Subject();
  }

  switchBlock(tab) {
    this.tabSub.next(tab);
  }

  openBlock(quote: BlockQuote) {
    this.currentBlock = quote;
    this.blockSub.next(quote);
  }

  openStock(quote) {
    let symbol = quote["symbol"].replace(".", "_");
    this.router.navigate(["/stock", symbol]);
  }

  getSuitableClass(params: QuoteHeader, value) {
    return Object.assign({}, {
      'text-go-up': params.withUpOrDown && value >= 0,
      'text-go-down': params.withUpOrDown && value < 0,
      'text-percent': params.withPercent
    }, this.getHeaderClass(params));
  }

  getHeaderClass(params: QuoteHeader) {
    let appendClass, activeClass;
    appendClass = params.class ? params.class.reduce((acc, cur) => Object.assign({}, acc, { [cur]: true }), {}) : {};
    activeClass = { 'active': this.quoteTable.currentState.sortBy == params.key };
    return Object.assign({}, appendClass, activeClass);
  }

  getBlockSymbol(block) {
    return block.symbol;
  }

  /**
   * 匹配股票对应的板块，取SS,SZ这类指数板块，过滤XBHS,XBHK这类沪深板块
   * 
   * @symbolList => 板块列表
   * return symbolSum => 由板块symbol构成的query string
   * return list => 由板块symbol构成的symbol列表
   */
  private getQueryParamsAndList(symbolList: string[]) {
    let quotation = "?";
    let list = [];

    symbolList
      .filter((symbol) => {
        return symbol.match(/([a-zA-Z0-9]{6}\.([a-zA-Z]{2})\.)/g);
      })
      .map((symbol) => {
        return symbol.replace(/\.[a-zA-Z]{2,4}$/, "");
      })
      .forEach((symbol) => {
        list.push(symbol);
        quotation = `${quotation}symbol=${symbol}&`;
      });

    console.debug("slice block symbols:", quotation, list);
    return { quotation, list };
  }

  ngOnInit() {
    let { http } = this;

    // 判断是否绑定了事件更新的Observable,如果没有则以路由参数为准 
    // if (!this.stockSource) {
    //   this.stockSource = this.activatedRoute.params;
    // }
    this.subscription = this.activatedRoute.params.switchMap(params => {
      console.debug("symbol Change: ", params);
      let id = params["id"].replace("_", ".");
      this.loader.showLoading("table");
      return http.get(`${BASEURL}/stock/symbol2blocks/${id}`);
    })
      .subscribe((data) => {
        console.debug("GOTTA DATA: ", data.length);

        this.loader.hideLoading("table");
        let listObj = this.getQueryParamsAndList(data);

        // unsubscribe
        if (this.blockList) {
          this.socket.emit('unsub', { channel: 'watchlist', symbols: this.blockList });
        }
        this.blockList = listObj.list;
        console.debug("blocks list: ", this.blockList);
        this.tabSub.next(listObj.quotation);
      }, err => {
        console.debug("query symbol2blocks err: ", err.json());
      });

    // this.stockSource
    //   .switchMap(params => {
    //     console.debug("stockSource symbol Change: ", params);
    //     return http.get(`${BASEURL}/stock/symbol2blocks/${params.symbol}`);
    //   })
    //   .subscribe(data => {
    //     console.debug("stockSource symbol Change: ", data);
    //     // let quotation = this.getQueryParamsAndList(data);
    //     // this.tabSub.next(quotation);
    //     let list = this.getFiltedSymbolList(data);
    //     this.tabSub.next(list);
    //   }, err => console.debug("query symbol2blocks err: ", err.json()));

    // this.stockParams = this.tabSub.subscribe(list => {
    //   return Observable.of({
    //     id: "ZS",
    //     dataUrl: `${BASEURL}/stock/summaries/quotation${getParams(list)}`
    //   });
    // });

    // 查询所属板块的涨幅数据
    this.subscription.add(
      this.stockParams = this.tabSub
      .distinctUntilChanged()
      .switchMap(quotation => {
        console.debug("stockParams Switch Map: ", quotation);
        return http.get(`${STOCKURL}/api/v2/sc/stocks/quotation${quotation}`, {});
      })
      .subscribe(res => {
        console.debug("stockparams blocks list res: ", res);
        if (res.isError || !res.data)
           return;
        res = res.data.filter(req => "change_rate" in req);
        this.blockData = res;
        this.currentBlock = this.blockData[0];
        // default click first block
        this.blockSub.next(this.currentBlock);

        if (this.blockList) {
          this.socket.emit('sub', { channel: 'watchlist', symbols: this.blockList });
        }
      })
    );

    // 动态更新板块的数据
    this.socket.on("watchlist", data => {
      // console.debug("socket data: ", data);
      let updateData = data; //adapt to v2 api
      //let updateData = Object.keys(data).map(key => data[key]).reduce(first => first);
      // console.debug("socket update updateData: ", updateData);

      this.blockData = this.blockData.map(row => {
        if (row['symbol'] === updateData['symbol']) {
          row = _.merge({}, row, updateData);
          // console.debug("socket update row: ", row);
        }
        return row;
      });
    });

    // 点击板块获取所属个股
    this.blockParams = this.blockSub.switchMap(quote => {
      console.debug("Switch Map: ", quote);
      return http.get(`${BASEURL}/stock/block2symbols/${quote.symbol}`);
    })
      .map(res => {
        console.debug("RES: ", res);
        return {
          id: res.type,
          dataUrl: `${BASEURL}/stock/summaries/dynpanel${getParams(res.symbols.slice(0, 50))}`
        };
      });
  }

  ngAfterViewInit() {
    console.debug("stock-block stockSource: ", this.stockSource, this.blockData);
    // this.blockSub.next(this.currentBlock);
  }

  ngOnDestroy() {
    if (this.subscription) {
      this.subscription.unsubscribe();
    }
  }

}